//
//  Emoji+SkinTone.swift
//  EmojiKit
//
//  Created by Daniel Saidi on 2023-11-01.
//  Copyright © 2023-2025 Daniel Saidi. All rights reserved.
//

import SwiftUI

public extension Emoji {

    /// Whether or not the emoji has any skin tone variants.
    var hasSkinToneVariants: Bool {
        char.hasEmojiSkinToneVariants
    }

    /// The emoji's neutral skin tone variant.
    var neutralSkinToneVariant: Emoji {
        if let override = neutralSkinToneVariantOverride { return override }
        return Emoji(char.neutralEmojiSkinToneVariant)
    }

    /// All skin tone variants for the emoji, if any.
    var skinToneVariants: [Emoji] {
        if let overrides = skinToneVariantOverrides { return overrides }
        guard hasSkinToneVariants else { return [] }
        let neutral = neutralSkinToneVariant
        let modifiers = String.emojiSkinToneModifiers
        let variants = modifiers.map { Emoji(neutral.char + $0) }
        return [neutral] + variants
    }
}

extension Emoji {

    var neutralSkinToneVariantOverride: Emoji? {
        skinToneVariantOverrides?.first
    }

    var skinToneVariantOverrides: [Emoji]? {
        let dict = Self.skinToneVariantOverrides
        let overrides = dict[char]
        return overrides?.map { .init($0) }
    }

    static let skinToneVariantOverrides: [String: String] = {
        skinToneVariantOverrideValues.toSkinToneLookupTable()
    }()

    static let skinToneVariantOverrideValues = [
        "☝️☝🏻☝🏼☝🏽☝🏾☝🏿",
        "✌️✌🏻✌🏼✌🏽✌🏾✌🏿",
        "✍️✍🏻✍🏼✍🏽✍🏾✍🏿",
        "👩‍🦱👩🏻‍🦱👩🏼‍🦱👩🏽‍🦱👩🏾‍🦱👩🏿‍🦱",
        "🧑‍🦱🧑🏻‍🦱🧑🏼‍🦱🧑🏽‍🦱🧑🏾‍🦱🧑🏿‍🦱",
        "👨‍🦱👨🏻‍🦱👨🏼‍🦱👨🏽‍🦱👨🏾‍🦱👨🏿‍🦱",
        "👩‍🦰👩🏻‍🦰👩🏼‍🦰👩🏽‍🦰👩🏾‍🦰👩🏿‍🦰",
        "🧑‍🦰🧑🏻‍🦰🧑🏼‍🦰🧑🏽‍🦰🧑🏾‍🦰🧑🏿‍🦰",
        "👨‍🦰👨🏻‍🦰👨🏼‍🦰👨🏽‍🦰👨🏾‍🦰👨🏿‍🦰",
        "👱‍♀️👱🏻‍♀️👱🏼‍♀️👱🏽‍♀️👱🏾‍♀️👱🏿‍♀️",
        "👱‍♂️👱🏻‍♂️👱🏼‍♂️👱🏽‍♂️👱🏾‍♂️👱🏿‍♂️",
        "👩‍🦳👩🏻‍🦳👩🏼‍🦳👩🏽‍🦳👩🏾‍🦳👩🏿‍🦳",
        "🧑‍🦳🧑🏻‍🦳🧑🏼‍🦳🧑🏽‍🦳🧑🏾‍🦳🧑🏿‍🦳",
        "👨‍🦳👨🏻‍🦳👨🏼‍🦳👨🏽‍🦳👨🏾‍🦳👨🏿‍🦳",
        "👩‍🦲👩🏻‍🦲👩🏼‍🦲👩🏽‍🦲👩🏾‍🦲👩🏿‍🦲",
        "🧑‍🦲🧑🏻‍🦲🧑🏼‍🦲🧑🏽‍🦲🧑🏾‍🦲🧑🏿‍🦲",
        "👨‍🦲👨🏻‍🦲👨🏼‍🦲👨🏽‍🦲👨🏾‍🦲👨🏿‍🦲",
        "🧔‍♀️🧔🏻‍♀️🧔🏼‍♀️🧔🏽‍♀️🧔🏾‍♀️🧔🏿‍♀️",
        "🧔🧔🏻🧔🏼🧔🏽🧔🏾🧔🏿",
        "🧔‍♂️🧔🏻‍♂️🧔🏼‍♂️🧔🏽‍♂️🧔🏾‍♂️🧔🏿‍♂️",
        "👮‍♀️👮🏻‍♀️👮🏼‍♀️👮🏽‍♀️👮🏾‍♀️👮🏿‍♀️",
        "👮👮🏻👮🏼👮🏽👮🏾👮🏿",
        "👮‍♂️👮🏻‍♂️👮🏼‍♂️👮🏽‍♂️👮🏾‍♂️👮🏿‍♂️",
        "👷‍♀️👷🏻‍♀️👷🏼‍♀️👷🏽‍♀️👷🏾‍♀️👷🏿‍♀️",
        "👷‍♂️👷🏻‍♂️👷🏼‍♂️👷🏽‍♂️👷🏾‍♂️👷🏿‍♂️",
        "👳‍♀️👳🏻‍♀️👳🏼‍♀️👳🏽‍♀️👳🏾‍♀️👳🏿‍♀️",
        "👳‍♂️👳🏻‍♂️👳🏼‍♂️👳🏽‍♂️👳🏾‍♂️👳🏿‍♂️",
        "💂‍♀️💂🏻‍♀️💂🏼‍♀️💂🏽‍♀️💂🏾‍♀️💂🏿‍♀️",
        "💂‍♂️💂🏻‍♂️💂🏼‍♂️💂🏽‍♂️💂🏾‍♂️💂🏿‍♂️",
        "🕵️‍♀️🕵🏻‍♀️🕵🏼‍♀️🕵🏽‍♀️🕵🏾‍♀️🕵🏿‍♀️",
        "🕵️🕵🏻🕵🏼🕵🏽🕵🏾🕵🏿",
        "🕵️‍♂️🕵🏻‍♂️🕵🏼‍♂️🕵🏽‍♂️🕵🏾‍♂️🕵🏿‍♂️",
        "👩‍⚕️👩🏻‍⚕️👩🏼‍⚕️👩🏽‍⚕️👩🏾‍⚕️👩🏿‍⚕️",
        "🧑‍⚕️🧑🏻‍⚕️🧑🏼‍⚕️🧑🏽‍⚕️🧑🏾‍⚕️🧑🏿‍⚕️",
        "👨‍⚕️👨🏻‍⚕️👨🏼‍⚕️👨🏽‍⚕️👨🏾‍⚕️👨🏿‍⚕️",
        "👩‍🌾👩🏻‍🌾👩🏼‍🌾👩🏽‍🌾👩🏾‍🌾👩🏿‍🌾",
        "🧑‍🌾🧑🏻‍🌾🧑🏼‍🌾🧑🏽‍🌾🧑🏾‍🌾🧑🏿‍🌾",
        "👨‍🌾👨🏻‍🌾👨🏼‍🌾👨🏽‍🌾👨🏾‍🌾👨🏿‍🌾",
        "👩‍🍳👩🏻‍🍳👩🏼‍🍳👩🏽‍🍳👩🏾‍🍳👩🏿‍🍳",
        "🧑‍🍳🧑🏻‍🍳🧑🏼‍🍳🧑🏽‍🍳🧑🏾‍🍳🧑🏿‍🍳",
        "👨‍🍳👨🏻‍🍳👨🏼‍🍳👨🏽‍🍳👨🏾‍🍳👨🏿‍🍳",
        "👩‍🎓👩🏻‍🎓👩🏼‍🎓👩🏽‍🎓👩🏾‍🎓👩🏿‍🎓",
        "🧑‍🎓🧑🏻‍🎓🧑🏼‍🎓🧑🏽‍🎓🧑🏾‍🎓🧑🏿‍🎓",
        "👨‍🎓👨🏻‍🎓👨🏼‍🎓👨🏽‍🎓👨🏾‍🎓👨🏿‍🎓",
        "🧑‍🎤🧑🏻‍🎤🧑🏼‍🎤🧑🏽‍🎤🧑🏾‍🎤🧑🏿‍🎤",
        "👨‍🎤👨🏻‍🎤👨🏼‍🎤👨🏽‍🎤👨🏾‍🎤👨🏿‍🎤",
        "👩‍🎤👩🏻‍🎤👩🏼‍🎤👩🏽‍🎤👩🏾‍🎤👩🏿‍🎤",
        "👩‍🏫👩🏻‍🏫👩🏼‍🏫👩🏽‍🏫👩🏾‍🏫👩🏿‍🏫",
        "🧑‍🏫🧑🏻‍🏫🧑🏼‍🏫🧑🏽‍🏫🧑🏾‍🏫🧑🏿‍🏫",
        "👨‍🏫👨🏻‍🏫👨🏼‍🏫👨🏽‍🏫👨🏾‍🏫👨🏿‍🏫",
        "👩‍🔬👩🏻‍🔬👩🏼‍🔬👩🏽‍🔬👩🏾‍🔬👩🏿‍🔬",
        "🧑‍🔬🧑🏻‍🔬🧑🏼‍🔬🧑🏽‍🔬🧑🏾‍🔬🧑🏿‍🔬",
        "👨‍🔬👨🏻‍🔬👨🏼‍🔬👨🏽‍🔬👨🏾‍🔬👨🏿‍🔬",
        "👩‍🏭👩🏻‍🏭👩🏼‍🏭👩🏽‍🏭👩🏾‍🏭👩🏿‍🏭",
        "🧑‍🏭🧑🏻‍🏭🧑🏼‍🏭🧑🏽‍🏭🧑🏾‍🏭🧑🏿‍🏭",
        "👨‍🔧👨🏻‍🔧👨🏼‍🔧👨🏽‍🔧👨🏾‍🔧👨🏿‍🔧",
        "👩‍💻👩🏻‍💻👩🏼‍💻👩🏽‍💻👩🏾‍💻👩🏿‍💻",
        "🧑‍💻🧑🏻‍💻🧑🏼‍💻🧑🏽‍💻🧑🏾‍💻🧑🏿‍💻",
        "👨‍💻👨🏻‍💻👨🏼‍💻👨🏽‍💻👨🏾‍💻👨🏿‍💻",
        "👩‍💼👩🏻‍💼👩🏼‍💼👩🏽‍💼👩🏾‍💼👩🏿‍💼",
        "🧑‍💼🧑🏻‍💼🧑🏼‍💼🧑🏽‍💼🧑🏾‍💼🧑🏿‍💼",
        "👨‍💼👨🏻‍💼👨🏼‍💼👨🏽‍💼👨🏾‍💼👨🏿‍💼",
        "👩‍🔧👩🏻‍🔧👩🏼‍🔧👩🏽‍🔧👩🏾‍🔧👩🏿‍🔧",
        "🧑‍🔧🧑🏻‍🔧🧑🏼‍🔧🧑🏽‍🔧🧑🏾‍🔧🧑🏿‍🔧",
        "👨‍🏭👨🏻‍🏭👨🏼‍🏭👨🏽‍🏭👨🏾‍🏭👨🏿‍🏭",
        "👩‍🎨👩🏻‍🎨👩🏼‍🎨👩🏽‍🎨👩🏾‍🎨👩🏿‍🎨",
        "🧑‍🎨🧑🏻‍🎨🧑🏼‍🎨🧑🏽‍🎨🧑🏾‍🎨🧑🏿‍🎨",
        "👨‍🎨👨🏻‍🎨👨🏼‍🎨👨🏽‍🎨👨🏾‍🎨👨🏿‍🎨",
        "👩‍🚒👩🏻‍🚒👩🏼‍🚒👩🏽‍🚒👩🏾‍🚒👩🏿‍🚒",
        "🧑‍🚒🧑🏻‍🚒🧑🏼‍🚒🧑🏽‍🚒🧑🏾‍🚒🧑🏿‍🚒",
        "👨‍🚒👨🏻‍🚒👨🏼‍🚒👨🏽‍🚒👨🏾‍🚒👨🏿‍🚒",
        "👩‍✈️👩🏻‍✈️👩🏼‍✈️👩🏽‍✈️👩🏾‍✈️👩🏿‍✈️",
        "🧑‍✈️🧑🏻‍✈️🧑🏼‍✈️🧑🏽‍✈️🧑🏾‍✈️🧑🏿‍✈️",
        "👨‍✈️👨🏻‍✈️👨🏼‍✈️👨🏽‍✈️👨🏾‍✈️👨🏿‍✈️",
        "👩‍🚀👩🏻‍🚀👩🏼‍🚀👩🏽‍🚀👩🏾‍🚀👩🏿‍🚀",
        "🧑‍🚀🧑🏻‍🚀🧑🏼‍🚀🧑🏽‍🚀🧑🏾‍🚀🧑🏿‍🚀",
        "👨‍🚀👨🏻‍🚀👨🏼‍🚀👨🏽‍🚀👨🏾‍🚀👨🏿‍🚀",
        "👩‍⚖️👩🏻‍⚖️👩🏼‍⚖️👩🏽‍⚖️👩🏾‍⚖️👩🏿‍⚖️",
        "🧑‍⚖️🧑🏻‍⚖️🧑🏼‍⚖️🧑🏽‍⚖️🧑🏾‍⚖️🧑🏿‍⚖️",
        "👨‍⚖️👨🏻‍⚖️👨🏼‍⚖️👨🏽‍⚖️👨🏾‍⚖️👨🏿‍⚖️",
        "👰‍♀️👰🏻‍♀️👰🏼‍♀️👰🏽‍♀️👰🏾‍♀️👰🏿‍♀️",
        "👰‍♂️👰🏻‍♂️👰🏼‍♂️👰🏽‍♂️👰🏾‍♂️👰🏿‍♂️",
        "🤵‍♀️🤵🏻‍♀️🤵🏼‍♀️🤵🏽‍♀️🤵🏾‍♀️🤵🏿‍♀️",
        "🤵‍♂️🤵🏻‍♂️🤵🏼‍♂️🤵🏽‍♂️🤵🏾‍♂️🤵🏿‍♂️",
        "🦸‍♀️🦸🏻‍♀️🦸🏼‍♀️🦸🏽‍♀️🦸🏾‍♀️🦸🏿‍♀️",
        "🦸‍♂️🦸🏻‍♂️🦸🏼‍♂️🦸🏽‍♂️🦸🏾‍♂️🦸🏿‍♂️",
        "🦹‍♀️🦹🏻‍♀️🦹🏼‍♀️🦹🏽‍♀️🦹🏾‍♀️🦹🏿‍♀️",
        "🦹‍♂️🦹🏻‍♂️🦹🏼‍♂️🦹🏽‍♂️🦹🏾‍♂️🦹🏿‍♂️",
        "🧝‍♀️🧝🏻‍♀️🧝🏼‍♀️🧝🏽‍♀️🧝🏾‍♀️🧝🏿‍♀️",
        "🧝‍♂️🧝🏻‍♂️🧝🏼‍♂️🧝🏽‍♂️🧝🏾‍♂️🧝🏿‍♂️",
        "🧑‍🎄🧑🏻‍🎄🧑🏼‍🎄🧑🏽‍🎄🧑🏾‍🎄🧑🏿‍🎄",
        "🧙‍♀️🧙🏻‍♀️🧙🏼‍♀️🧙🏽‍♀️🧙🏾‍♀️🧙🏿‍♀️",
        "🧙‍♂️🧙🏻‍♂️🧙🏼‍♂️🧙🏽‍♂️🧙🏾‍♂️🧙🏿‍♂️",
        "🧛‍♀️🧛🏻‍♀️🧛🏼‍♀️🧛🏽‍♀️🧛🏾‍♀️🧛🏿‍♀️",
        "🧛‍♂️🧛🏻‍♂️🧛🏼‍♂️🧛🏽‍♂️🧛🏾‍♂️🧛🏿‍♂️",
        "🧜‍♀️🧜🏻‍♀️🧜🏼‍♀️🧜🏽‍♀️🧜🏾‍♀️🧜🏿‍♀️",
        "🧜‍♂️🧜🏻‍♂️🧜🏼‍♂️🧜🏽‍♂️🧜🏾‍♂️🧜🏿‍♂️",
        "🧚‍♀️🧚🏻‍♀️🧚🏼‍♀️🧚🏽‍♀️🧚🏾‍♀️🧚🏿‍♀️",
        "🧚‍♂️🧚🏻‍♂️🧚🏼‍♂️🧚🏽‍♂️🧚🏾‍♂️🧚🏿‍♂️",
        "👩‍🍼👩🏻‍🍼👩🏼‍🍼👩🏽‍🍼👩🏾‍🍼👩🏿‍🍼",
        "🧑‍🍼🧑🏻‍🍼🧑🏼‍🍼🧑🏽‍🍼🧑🏾‍🍼🧑🏿‍🍼",
        "👨‍🍼👨🏻‍🍼👨🏼‍🍼👨🏽‍🍼👨🏾‍🍼👨🏿‍🍼",
        "🙇‍♀️🙇🏻‍♀️🙇🏼‍♀️🙇🏽‍♀️🙇🏾‍♀️🙇🏿‍♀️",
        "🙇‍♂️🙇🏻‍♂️🙇🏼‍♂️🙇🏽‍♂️🙇🏾‍♂️🙇🏿‍♂️",
        "💁‍♀️💁🏻‍♀️💁🏼‍♀️💁🏽‍♀️💁🏾‍♀️💁🏿‍♀️",
        "💁‍♂️💁🏻‍♂️💁🏼‍♂️💁🏽‍♂️💁🏾‍♂️💁🏿‍♂️",
        "🙅‍♀️🙅🏻‍♀️🙅🏼‍♀️🙅🏽‍♀️🙅🏾‍♀️🙅🏿‍♀️",
        "🙅‍♂️🙅🏻‍♂️🙅🏼‍♂️🙅🏽‍♂️🙅🏾‍♂️🙅🏿‍♂️",
        "🙆‍♀️🙆🏻‍♀️🙆🏼‍♀️🙆🏽‍♀️🙆🏾‍♀️🙆🏿‍♀️",
        "🙆‍♂️🙆🏻‍♂️🙆🏼‍♂️🙆🏽‍♂️🙆🏾‍♂️🙆🏿‍♂️",
        "🙋‍♀️🙋🏻‍♀️🙋🏼‍♀️🙋🏽‍♀️🙋🏾‍♀️🙋🏿‍♀️",
        "🙋‍♂️🙋🏻‍♂️🙋🏼‍♂️🙋🏽‍♂️🙋🏾‍♂️🙋🏿‍♂️",
        "🧏‍♀️🧏🏻‍♀️🧏🏼‍♀️🧏🏽‍♀️🧏🏾‍♀️🧏🏿‍♀️",
        "🧏‍♂️🧏🏻‍♂️🧏🏼‍♂️🧏🏽‍♂️🧏🏾‍♂️🧏🏿‍♂️",
        "🤦‍♀️🤦🏻‍♀️🤦🏼‍♀️🤦🏽‍♀️🤦🏾‍♀️🤦🏿‍♀️",
        "🤦‍♂️🤦🏻‍♂️🤦🏼‍♂️🤦🏽‍♂️🤦🏾‍♂️🤦🏿‍♂️",
        "🤷‍♀️🤷🏻‍♀️🤷🏼‍♀️🤷🏽‍♀️🤷🏾‍♀️🤷🏿‍♀️",
        "🤷‍♂️🤷🏻‍♂️🤷🏼‍♂️🤷🏽‍♂️🤷🏾‍♂️🤷🏿‍♂️",
        "🙎‍♀️🙎🏻‍♀️🙎🏼‍♀️🙎🏽‍♀️🙎🏾‍♀️🙎🏿‍♀️",
        "🙎‍♂️🙎🏻‍♂️🙎🏼‍♂️🙎🏽‍♂️🙎🏾‍♂️🙎🏿‍♂️",
        "🙍‍♀️🙍🏻‍♀️🙍🏼‍♀️🙍🏽‍♀️🙍🏾‍♀️🙍🏿‍♀️",
        "🙍‍♂️🙍🏻‍♂️🙍🏼‍♂️🙍🏽‍♂️🙍🏾‍♂️🙍🏿‍♂️",
        "💇‍♀️💇🏻‍♀️💇🏼‍♀️💇🏽‍♀️💇🏾‍♀️💇🏿‍♀️",
        "💇‍♂️💇🏻‍♂️💇🏼‍♂️💇🏽‍♂️💇🏾‍♂️💇🏿‍♂️",
        "💆‍♀️💆🏻‍♀️💆🏼‍♀️💆🏽‍♀️💆🏾‍♀️💆🏿‍♀️",
        "💆‍♂️💆🏻‍♂️💆🏼‍♂️💆🏽‍♂️💆🏾‍♂️💆🏿‍♂️",
        "🧖‍♀️🧖🏻‍♀️🧖🏼‍♀️🧖🏽‍♀️🧖🏾‍♀️🧖🏿‍♀️",
        "🧖‍♂️🧖🏻‍♂️🧖🏼‍♂️🧖🏽‍♂️🧖🏾‍♂️🧖🏿‍♂️",
        "👩‍🦽👩🏻‍🦽👩🏼‍🦽👩🏽‍🦽👩🏾‍🦽👩🏿‍🦽",
        "🧑‍🦽🧑🏻‍🦽🧑🏼‍🦽🧑🏽‍🦽🧑🏾‍🦽🧑🏿‍🦽",
        "👨‍🦽👨🏻‍🦽👨🏼‍🦽👨🏽‍🦽👨🏾‍🦽👨🏿‍🦽",
        "👩‍🦽‍➡️👩🏻‍🦽‍➡️👩🏼‍🦽‍➡️👩🏽‍🦽‍➡️👩🏾‍🦽‍➡️👩🏿‍🦽‍➡️",
        "🧑‍🦽‍➡️🧑🏻‍🦽‍➡️🧑🏼‍🦽‍➡️🧑🏽‍🦽‍➡️🧑🏾‍🦽‍➡️🧑🏿‍🦽‍➡️",
        "👨‍🦽‍➡️👨🏻‍🦽‍➡️👨🏼‍🦽‍➡️👨🏽‍🦽‍➡️👨🏾‍🦽‍➡️👨🏿‍🦽‍➡️",
        "👩‍🦼👩🏻‍🦼👩🏼‍🦼👩🏽‍🦼👩🏾‍🦼👩🏿‍🦼",
        "🧑‍🦼🧑🏻‍🦼🧑🏼‍🦼🧑🏽‍🦼🧑🏾‍🦼🧑🏿‍🦼",
        "👨‍🦼👨🏻‍🦼👨🏼‍🦼👨🏽‍🦼👨🏾‍🦼👨🏿‍🦼",
        "👩‍🦼‍➡️👩🏻‍🦼‍➡️👩🏼‍🦼‍➡️👩🏽‍🦼‍➡️👩🏾‍🦼‍➡️👩🏿‍🦼‍➡️",
        "🧑‍🦼‍➡️🧑🏻‍🦼‍➡️🧑🏼‍🦼‍➡️🧑🏽‍🦼‍➡️🧑🏾‍🦼‍➡️🧑🏿‍🦼‍➡️",
        "👨‍🦼‍➡️👨🏻‍🦼‍➡️👨🏼‍🦼‍➡️👨🏽‍🦼‍➡️👨🏾‍🦼‍➡️👨🏿‍🦼‍➡️",
        "🚶‍♀️🚶🏻‍♀️🚶🏼‍♀️🚶🏽‍♀️🚶🏾‍♀️🚶🏿‍♀️",
        "🚶🚶🏻🚶🏼🚶🏽🚶🏾🚶🏿",
        "🚶‍♂️🚶🏻‍♂️🚶🏼‍♂️🚶🏽‍♂️🚶🏾‍♂️🚶🏿‍♂️",
        "🚶‍♀️‍➡️🚶🏻‍♀️‍➡️🚶🏼‍♀️‍➡️🚶🏽‍♀️‍➡️🚶🏾‍♀️‍➡️🚶🏿‍♀️‍➡️",
        "🚶‍➡️🚶🏻‍➡️🚶🏼‍➡️🚶🏽‍➡️🚶🏾‍➡️🚶🏿‍➡️",
        "🚶‍♂️‍➡️🚶🏻‍♂️‍➡️🚶🏼‍♂️‍➡️🚶🏽‍♂️‍➡️🚶🏾‍♂️‍➡️🚶🏿‍♂️‍➡️",
        "👩‍🦯👩🏻‍🦯👩🏼‍🦯👩🏽‍🦯👩🏾‍🦯👩🏿‍🦯",
        "🧑‍🦯🧑🏻‍🦯🧑🏼‍🦯🧑🏽‍🦯🧑🏾‍🦯🧑🏿‍🦯",
        "👨‍🦯👨🏻‍🦯👨🏼‍🦯👨🏽‍🦯👨🏾‍🦯👨🏿‍🦯",
        "👩‍🦯‍➡️👩🏻‍🦯‍➡️👩🏼‍🦯‍➡️👩🏽‍🦯‍➡️👩🏾‍🦯‍➡️👩🏿‍🦯‍➡️",
        "🧑‍🦯‍➡️🧑🏻‍🦯‍➡️🧑🏼‍🦯‍➡️🧑🏽‍🦯‍➡️🧑🏾‍🦯‍➡️🧑🏿‍🦯‍➡️",
        "👨‍🦯‍➡️👨🏻‍🦯‍➡️👨🏼‍🦯‍➡️👨🏽‍🦯‍➡️👨🏾‍🦯‍➡️👨🏿‍🦯‍➡️",
        "🧎‍♀️🧎🏻‍♀️🧎🏼‍♀️🧎🏽‍♀️🧎🏾‍♀️🧎🏿‍♀️",
        "🧎‍♀️🧎🏻‍♀️🧎🏼‍♀️🧎🏽‍♀️🧎🏾‍♀️🧎🏿‍♀️",
        "🧎🧎🏻🧎🏼🧎🏽🧎🏾🧎🏿",
        "🧎‍♂️🧎🏻‍♂️🧎🏼‍♂️🧎🏽‍♂️🧎🏾‍♂️🧎🏿‍♂️",
        "🧎‍♀️‍➡️🧎🏻‍♀️‍➡️🧎🏼‍♀️‍➡️🧎🏽‍♀️‍➡️🧎🏾‍♀️‍➡️🧎🏿‍♀️‍➡️",
        "🧎‍➡️🧎🏻‍➡️🧎🏼‍➡️🧎🏽‍➡️🧎🏾‍➡️🧎🏿‍➡️",
        "🧎‍♂️‍➡️🧎🏻‍♂️‍➡️🧎🏼‍♂️‍➡️🧎🏽‍♂️‍➡️🧎🏾‍♂️‍➡️🧎🏿‍♂️‍➡️",
        "🏃‍♀️🏃🏻‍♀️🏃🏼‍♀️🏃🏽‍♀️🏃🏾‍♀️🏃🏿‍♀️",
        "🏃🏃🏻🏃🏼🏃🏽🏃🏾🏃🏿",
        "🏃‍♂️🏃🏻‍♂️🏃🏼‍♂️🏃🏽‍♂️🏃🏾‍♂️🏃🏿‍♂️",
        "🏃‍♀️‍➡️🏃🏻‍♀️‍➡️🏃🏼‍♀️‍➡️🏃🏽‍♀️‍➡️🏃🏾‍♀️‍➡️🏃🏿‍♀️‍➡️",
        "🏃‍➡️🏃🏻‍➡️🏃🏼‍➡️🏃🏽‍➡️🏃🏾‍➡️🏃🏿‍➡️",
        "🏃‍♂️‍➡️🏃🏻‍♂️‍➡️🏃🏼‍♂️‍➡️🏃🏽‍♂️‍➡️🏃🏾‍♂️‍➡️🏃🏿‍♂️‍➡️",
        "🧍‍♀️🧍🏻‍♀️🧍🏼‍♀️🧍🏽‍♀️🧍🏾‍♀️🧍🏿‍♀️",
        "🧍‍♂️🧍🏻‍♂️🧍🏼‍♂️🧍🏽‍♂️🧍🏾‍♂️🧍🏿‍♂️",
        "🏋️‍♀️🏋🏻‍♀️🏋🏼‍♀️🏋🏽‍♀️🏋🏾‍♀️🏋🏿‍♀️",
        "🏋️🏋🏻🏋🏼🏋🏽🏋🏾🏋🏿",
        "🏋️‍♂️🏋🏻‍♂️🏋🏼‍♂️🏋🏽‍♂️🏋🏾‍♂️🏋🏿‍♂️",
        "⛹️⛹🏻⛹🏼⛹🏽⛹🏾⛹🏿",
        "⛹️‍♀️⛹🏻⛹🏼⛹🏽⛹🏾⛹🏿",
        "⛹️‍♂️⛹🏻⛹🏼⛹🏽⛹🏾⛹🏿",
        "🏌️‍♀️🏌🏻‍♀️🏌🏼‍♀️🏌🏽‍♀️🏌🏾‍♀️🏌🏿‍♀️",
        "🏌️🏌🏻🏌🏼🏌🏽🏌🏾🏌🏿",
        "🏌️‍♂️🏌🏻‍♂️🏌🏼‍♂️🏌🏽‍♂️🏌🏾‍♂️🏌🏿‍♂️",
        "🤸‍♀️🤸🏻‍♀️🤸🏼‍♀️🤸🏽‍♀️🤸🏾‍♀️🤸🏿‍♀️",
        "🤸‍♂️🤸🏻‍♂️🤸🏼‍♂️🤸🏽‍♂️🤸🏾‍♂️🤸🏿‍♂️",
        "🤾‍♀️🤾🏻‍♀️🤾🏼‍♀️🤾🏽‍♀️🤾🏾‍♀️🤾🏿‍♀️",
        "🤾‍♂️🤾🏻‍♂️🤾🏼‍♂️🤾🏽‍♂️🤾🏾‍♂️🤾🏿‍♂️",
        "🧘‍♀️🧘🏻‍♀️🧘🏼‍♀️🧘🏽‍♀️🧘🏾‍♀️🧘🏿‍♀️",
        "🧘‍♂️🧘🏻‍♂️🧘🏼‍♂️🧘🏽‍♂️🧘🏾‍♂️🧘🏿‍♂️",
        "🏄‍♀️🏄🏻‍♀️🏄🏼‍♀️🏄🏽‍♀️🏄🏾‍♀️🏄🏿‍♀️",
        "🏄‍♂️🏄🏻‍♂️🏄🏼‍♂️🏄🏽‍♂️🏄🏾‍♂️🏄🏿‍♂️",
        "🏊‍♀️🏊🏻‍♀️🏊🏼‍♀️🏊🏽‍♀️🏊🏾‍♀️🏊🏿‍♀️",
        "🏊🏊🏻🏊🏼🏊🏽🏊🏾🏊🏿",
        "🏊‍♂️🏊🏻‍♂️🏊🏼‍♂️🏊🏽‍♂️🏊🏾‍♂️🏊🏿‍♂️",
        "🤽‍♀️🤽🏻‍♀️🤽🏼‍♀️🤽🏽‍♀️🤽🏾‍♀️🤽🏿‍♀️",
        "🤽‍♂️🤽🏻‍♂️🤽🏼‍♂️🤽🏽‍♂️🤽🏾‍♂️🤽🏿‍♂️",
        "🚣‍♀️🚣🏻‍♀️🚣🏼‍♀️🚣🏽‍♀️🚣🏾‍♀️🚣🏿‍♀️",
        "🚣‍♂️🚣🏻‍♂️🚣🏼‍♂️🚣🏽‍♂️🚣🏾‍♂️🚣🏿‍♂️",
        "🧗‍♀️🧗🏻‍♀️🧗🏼‍♀️🧗🏽‍♀️🧗🏾‍♀️🧗🏿‍♀️",
        "🧗🧗🏻🧗🏼🧗🏽🧗🏾🧗🏿",
        "🧗‍♂️🧗🏻‍♂️🧗🏼‍♂️🧗🏽‍♂️🧗🏾‍♂️🧗🏿‍♂️",
        "🤹‍♀️🤹🏻‍♀️🤹🏼‍♀️🤹🏽‍♀️🤹🏾‍♀️🤹🏿‍♀️",
        "🤹‍♂️🤹🏻‍♂️🤹🏼‍♂️🤹🏽‍♂️🤹🏾‍♂️🤹🏿‍♂️",
        "🚵‍♀️🚵🏻‍♀️🚵🏼‍♀️🚵🏽‍♀️🚵🏾‍♀️🚵🏿‍♀️",
        "🚵‍♂️🚵🏻‍♂️🚵🏼‍♂️🚵🏽‍♂️🚵🏾‍♂️🚵🏿‍♂️",
        "🚴‍♀️🚴🏻‍♀️🚴🏼‍♀️🚴🏽‍♀️🚴🏾‍♀️🚴🏿‍♀️",
        "🚴‍♂️🚴🏻‍♂️🚴🏼‍♂️🚴🏽‍♂️🚴🏾‍♂️🚴🏿‍♂️"
    ]
}

private extension String {

    static let emojiReferenceSize = "👍".emojiSize

    static let emojiSkinToneModifiers = ["🏻", "🏼", "🏽", "🏾", "🏿"]

    var emojiSize: CGSize {
        let greatestFinite = CGFloat.greatestFiniteMagnitude
        let size = CGSize(width: greatestFinite, height: greatestFinite)
        let rect = (self as NSString).boundingRect(
            with: size,
            options: .usesLineFragmentOrigin,
            context: nil)
        return rect.size
    }

    var hasEmojiSkinToneVariants: Bool {
        if isEmpty { return false }
        let modifier = Self.emojiSkinToneModifiers[0]
        let modified = neutralEmojiSkinToneVariant + modifier
        let size = modified.emojiSize
        return size == String.emojiReferenceSize
    }

    var neutralEmojiSkinToneVariant: String {
        if isEmpty { return self }
        guard let scalar = unicodeScalars.first else { return self }
        return String(scalar)
    }
}

private extension Array where Element == String {

    /**
     This function is used to make sure that every skin tone
     variant in every override is a key in the override dict.
     */
    func toSkinToneLookupTable() -> [String: String] {
        let dicts = map { string in
            let chars = string.map(String.init)
            return Dictionary(uniqueKeysWithValues: chars.map { ($0, string) })
        }
        var result = [String: String]()
        dicts.forEach {
            result.merge($0) { (current, _) in current }
        }
        return result
    }
}


#Preview {

    struct Preview: View {

        let emojis = "☝️✌️✍️👨🏻‍🚒".map { Emoji($0) }

        var body: some View {
            List {
                ForEach(emojis) { emoji in
                    HStack {
                        Text(emoji.char)
                        Divider()
                        ForEach(emoji.skinToneVariants) { Text($0.char)
                        }
                    }
                }
            }
        }
    }

    return Preview()
}
